home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / model.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  24.4 KB  |  850 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. import os
  5. import sys
  6. import time
  7. import socket
  8. import poplib
  9. import imaplib
  10. import threading
  11. import win32process
  12. from win32api import GetConsoleTitle
  13. from win32api import GetCurrentThread
  14. from win32api import error as win32api_error
  15. from spamexperts.Options import options
  16. from se_config import spamexpertsConfig
  17. from spamexperts.OptionsClass import IS_HAM, IS_SPAM, IS_UNSURE
  18. from spamexperts import se_state
  19. state = se_state.state
  20. from spamexperts import server
  21. VIEW_SPAM = 0
  22. VIEW_UNSURE = 1
  23. VIEW_HAM = 2
  24. VIEW_BLACK = 3
  25. VIEW_WHITE = 4
  26.  
  27. class Message(object):
  28.     
  29.     def __init__(self, sender = '', recipient = '', subject = '', body = ''):
  30.         self.sender = sender
  31.         self.recipient = recipient
  32.         self.subject = subject
  33.         self.body = body
  34.  
  35.  
  36.  
  37. class SEModel(object):
  38.     views = []
  39.     
  40.     def __init__(self, mutex):
  41.         self.started = False
  42.         self.ham_list = { }
  43.         self.unsure_list = { }
  44.         self.spam_list = { }
  45.         self.white_list = { }
  46.         self.black_list = { }
  47.         self.filter_spam = ''
  48.         self.filter_unsure = ''
  49.         self.filter_ham = ''
  50.         self.added_ham = []
  51.         self.added_unsure = []
  52.         self.added_spam = []
  53.         self.removed_ham = []
  54.         self.removed_unsure = []
  55.         self.removed_spam = []
  56.         self.threads = []
  57.         self.lsp_on = state.isLSPEnabled()
  58.         self.updating = False
  59.         self.settings = spamexpertsConfig
  60.         self.state = state
  61.         self.state.platform_mutex = mutex
  62.         self.exit_func = None
  63.         self.exit_args = None
  64.         self.exit_kwargs = None
  65.  
  66.     
  67.     def init(self, tray):
  68.         '''Initialise the model.'''
  69.         self.tray = tray
  70.         state.model_notifier = tray
  71.         state.init()
  72.         self.active = VIEW_SPAM
  73.         self.server_thread = threading.Thread(target = server.start, args = (tray,))
  74.         self.server_thread.setDaemon(True)
  75.         self.server_thread.start()
  76.         self.periodic_thread = threading.Thread(target = self.periodic)
  77.         self.periodic_thread.setDaemon(True)
  78.         self.periodic_thread.start()
  79.         self.running = True
  80.         self.initiate_check = False
  81.  
  82.     
  83.     def periodic(self):
  84.         below_normal = win32process.THREAD_PRIORITY_BELOW_NORMAL
  85.         win32process.SetThreadPriority(GetCurrentThread(), below_normal)
  86.         pop3 = pop3
  87.         import spamexperts
  88.         imap4 = imap4
  89.         import spamexperts
  90.         self.retriever = pop3.POPRetriever()
  91.         self.imap_filter = imap4.IMAPFilter()
  92.         self.retriever.state = state
  93.         self.imap_filter.state = state
  94.         queue = state.reclassifier.processing_queue
  95.         self.retriever.processing_queue = queue
  96.         self.imap_filter.processing_queue = queue
  97.         breather = 0.050000000000000003
  98.         while True:
  99.             self.initiate_check = False
  100.             if server.stop_server:
  101.                 break
  102.             
  103.             if self.settings.enable_periodic and self.settings.period and self.settings.block_spam:
  104.                 for connection in self.settings.periodic:
  105.                     (server_, port, user, pass_, proto, use_ssl) = connection
  106.                     if proto == 'pop3':
  107.                         self.periodic_pop3(server_, port, user, pass_, use_ssl)
  108.                     elif proto == 'imap4':
  109.                         self.periodic_imap4(server_, port, user, pass_, use_ssl)
  110.                     else:
  111.                         print >>sys.stderr, 'Unknown protocol.'
  112.                     time.sleep(breather)
  113.                 
  114.                 for unused in xrange(self.settings.period * 600 - int(breather * len(self.settings.periodic))):
  115.                     time.sleep(0.10000000000000001)
  116.                     if server.stop_server or self.initiate_check:
  117.                         break
  118.                         continue
  119.                 
  120.             time.sleep(1)
  121.         if options[('globals', 'verbose')]:
  122.             print 'Closed periodic thread.'
  123.         
  124.  
  125.     
  126.     def periodic_imap4(self, server_, port, user, pass_, use_ssl):
  127.         account = '%s_%s_IMAP' % (user, server_)
  128.         if not pass_:
  129.             if options[('globals', 'verbose')]:
  130.                 print "Don't know password for", account, 'yet, skipping.'
  131.             
  132.             return None
  133.         
  134.         
  135.         try:
  136.             if use_ssl:
  137.                 i = imaplib.IMAP4_SSL(server_, port)
  138.             else:
  139.                 i = imaplib.IMAP4(server_, port)
  140.         except Exception:
  141.             e = None
  142.             print >>sys.stderr, "Can't do automatic login", str(e)
  143.             return None
  144.  
  145.         user = user.strip('"')
  146.         pass_ = pass_.strip('"')
  147.         
  148.         try:
  149.             i.login(user, pass_)
  150.         except (imaplib.IMAP4.error, socket.error):
  151.             e = None
  152.             print >>sys.stderr, 'Could not login to IMAP server', user, server_
  153.             print >>sys.stderr, str(e)
  154.             return None
  155.  
  156.         self.imap_filter.current_account = account
  157.         state.open_remote_connections.append(account)
  158.         state.proxies.append(self.imap_filter)
  159.         self.imap_filter.load_folders_to_filter()
  160.         if options[('globals', 'verbose')]:
  161.             print 'Initiating automatic delete', account, time.asctime(time.localtime())
  162.         
  163.         
  164.         try:
  165.             self.imap_filter.expungeMessages(i)
  166.         except KeyError:
  167.             print "Don't know about", account, 'yet; skipping.'
  168.             i.logout()
  169.             state.open_remote_connections.remove(account)
  170.             state.proxies.remove(self.imap_filter)
  171.             return None
  172.  
  173.         if options[('globals', 'verbose')]:
  174.             print 'Initiating automatic', account, time.asctime(time.localtime())
  175.         
  176.         self.imap_filter.updateMessageDatabase(i)
  177.         self.imap_filter.close()
  178.         if options[('globals', 'verbose')]:
  179.             print 'Automatic complete', account, time.asctime(time.localtime())
  180.         
  181.  
  182.     
  183.     def periodic_pop3(self, server_, port, user, pass_, use_ssl):
  184.         account = '%s_%s_POP' % (user, server_)
  185.         if not pass_:
  186.             if options[('globals', 'verbose')]:
  187.                 print "Don't know password for", account, 'yet, skipping.'
  188.             
  189.             return None
  190.         
  191.         pop3 = pop3
  192.         import spamexperts
  193.         if use_ssl:
  194.             pop_class = pop3.POP3_SSL
  195.         else:
  196.             pop_class = pop3.POP3
  197.         
  198.         try:
  199.             self.retriever.remote_server = pop_class(state.logFile, server_, port)
  200.         except Exception:
  201.             e = None
  202.             print >>sys.stderr, "Can't do automatic login", str(e)
  203.             return None
  204.  
  205.         self.retriever.serverName = server_
  206.         
  207.         try:
  208.             self.retriever.remote_server.user(user)
  209.         except poplib.error_proto:
  210.             e = None
  211.             print >>sys.stderr, "Can't do automatic login (user)", str(e)
  212.             return None
  213.  
  214.         
  215.         try:
  216.             self.retriever.remote_server.pass_(pass_)
  217.         except poplib.error_proto:
  218.             e = None
  219.             print >>sys.stderr, "Can't do automatic login (pass)", str(e)
  220.             return None
  221.  
  222.         self.retriever.current_account = account
  223.         self.state.open_remote_connections.append(self.retriever.current_account)
  224.         state.reclassifier.current_account = account
  225.         state.proxies.append(self.retriever)
  226.         if options[('globals', 'verbose')]:
  227.             print 'Initiating automatic delete', account, time.asctime(time.localtime())
  228.         
  229.         
  230.         try:
  231.             self.retriever.delete_messages(self.retriever.remote_server)
  232.         except KeyError:
  233.             print "Don't know about", account, 'yet; skipping.'
  234.             self.retriever.remote_server.quit()
  235.             state.proxies.remove(self.retriever)
  236.             state.open_remote_connections.remove(account)
  237.             self.retriever.close()
  238.             return None
  239.         except socket.error:
  240.             e = None
  241.             print 'Error occured during periodic deletion', str(e)
  242.             state.proxies.remove(self.retriever)
  243.             state.open_remote_connections.remove(account)
  244.             self.retriever.close()
  245.             return None
  246.  
  247.         if options[('globals', 'verbose')]:
  248.             print 'Initiating automatic', account, time.asctime(time.localtime())
  249.         
  250.         
  251.         try:
  252.             self.retriever.retrieveMessages()
  253.         except Exception:
  254.             e = None
  255.             print 'Error occured during periodic retrieval', str(e)
  256.             state.proxies.remove(self.retriever)
  257.             state.open_remote_connections.remove(account)
  258.             self.retriever.close()
  259.             return None
  260.  
  261.         self.retriever.close()
  262.         if options[('globals', 'verbose')]:
  263.             print 'Automatic complete', account, time.asctime(time.localtime())
  264.         
  265.  
  266.     
  267.     def AddView(self, view):
  268.         if view not in self.views:
  269.             self.views.append(view)
  270.         
  271.  
  272.     
  273.     def UpdateViews(self, refresh = False):
  274.         self.updating = True
  275.         self._GetHam(refresh)
  276.         self._GetUnsure(refresh)
  277.         self._GetSpam(refresh)
  278.         for view in self.views:
  279.             view.UpdateView(self)
  280.         
  281.         self.updating = False
  282.  
  283.     
  284.     def AlreadyOn(self):
  285.         return self.started
  286.  
  287.     
  288.     def OkToStart(self):
  289.         if options[('pop3proxy', 'remote_servers')] and options[('imap4proxy', 'remote_servers')] or self.lsp_on:
  290.             return (True, _(''))
  291.         
  292.         return (False, 'LSP is not registered.')
  293.  
  294.     
  295.     def set_exit_action(self, func, args, kwargs):
  296.         self.exit_func = func
  297.         self.exit_args = args
  298.         self.exit_kwargs = kwargs
  299.  
  300.     
  301.     def Exit(self, callback = None):
  302.         if options[('globals', 'verbose')]:
  303.             print 'Waiting for other threads...'
  304.         
  305.         for thread in self.threads:
  306.             thread.join()
  307.         
  308.         state.quit = True
  309.         server.stop(callback)
  310.         if hasattr(self, 'periodic_thread'):
  311.             if options[('globals', 'verbose')]:
  312.                 print 'Waiting for periodic thread to finish...'
  313.             
  314.             self.periodic_thread.join()
  315.         
  316.         if hasattr(self, 'server_thread'):
  317.             if options[('globals', 'verbose')]:
  318.                 print 'Waiting for asyncore to finish...'
  319.             
  320.             self.server_thread.join()
  321.             if options[('globals', 'verbose')]:
  322.                 print 'Asyncore is finished.'
  323.             
  324.         
  325.         self.running = False
  326.         if self.exit_func:
  327.             self.exit_func(*self.exit_args, **self.exit_kwargs)
  328.         
  329.         print 'Model is closed.'
  330.  
  331.     
  332.     def StartStop(self):
  333.         self.UpdateViews()
  334.  
  335.     
  336.     def SetActive(self, view):
  337.         self.active = view
  338.         self.filter_spam = self.filter_ham = self.filter_unsure = ''
  339.         self.UpdateViews()
  340.  
  341.     
  342.     def _GetSpam(self, refresh = False):
  343.         ret = { }
  344.         if refresh:
  345.             self._SEModel__ham = state.getHamMessagesHeaders()
  346.             self._SEModel__unsure = state.getUnsureMessagesHeaders()
  347.             self._SEModel__spam = state.getSpamMessagesHeaders()
  348.         
  349.         for key, item in self._SEModel__spam.items():
  350.             (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
  351.             if msgid not in self.removed_spam:
  352.                 ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
  353.                 continue
  354.         
  355.         others = self._SEModel__ham.items()
  356.         others.extend(self._SEModel__unsure.items())
  357.         for key, item in others:
  358.             (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
  359.             if msgid in self.added_spam:
  360.                 ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
  361.                 continue
  362.         
  363.         self.spam_list = ret
  364.  
  365.     
  366.     def GetSpam(self):
  367.         filter_spam = self.filter_spam.strip().lower()
  368.         filtered_spam = _[1]
  369.         return dict(filtered_spam)
  370.  
  371.     
  372.     def _GetHam(self, refresh = False):
  373.         ret = { }
  374.         if refresh:
  375.             self._SEModel__ham = state.getHamMessagesHeaders()
  376.             self._SEModel__unsure = state.getUnsureMessagesHeaders()
  377.             self._SEModel__spam = state.getSpamMessagesHeaders()
  378.         
  379.         for key, item in self._SEModel__ham.items():
  380.             (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
  381.             if msgid not in self.removed_ham:
  382.                 ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
  383.                 continue
  384.         
  385.         others = self._SEModel__spam.items()
  386.         others.extend(self._SEModel__unsure.items())
  387.         for key, item in others:
  388.             (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
  389.             if msgid in self.added_ham:
  390.                 ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
  391.                 continue
  392.         
  393.         self.ham_list = ret
  394.  
  395.     
  396.     def GetHam(self):
  397.         filter_ham = self.filter_ham.strip().lower()
  398.         filtered_ham = _[1]
  399.         return dict(filtered_ham)
  400.  
  401.     
  402.     def _GetUnsure(self, refresh = False):
  403.         ret = { }
  404.         if refresh:
  405.             self._SEModel__ham = state.getHamMessagesHeaders()
  406.             self._SEModel__unsure = state.getUnsureMessagesHeaders()
  407.             self._SEModel__spam = state.getSpamMessagesHeaders()
  408.         
  409.         for key, item in self._SEModel__unsure.items():
  410.             (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
  411.             if msgid not in self.removed_unsure:
  412.                 ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
  413.                 continue
  414.         
  415.         others = self._SEModel__spam.items()
  416.         others.extend(self._SEModel__ham.items())
  417.         for key, item in others:
  418.             (msgfrom, emailsubject, emaildate, emailbody, msgto, emaildisposition, msgid, realfrom) = item
  419.             if msgid in self.added_unsure:
  420.                 ret[key] = (msgfrom, emailsubject, emaildate, msgid, msgto, realfrom)
  421.                 continue
  422.         
  423.         self.unsure_list = ret
  424.  
  425.     
  426.     def GetUnsure(self):
  427.         filter_unsure = self.filter_unsure.strip().lower()
  428.         filtered_unsure = _[1]
  429.         return dict(filtered_unsure)
  430.  
  431.     
  432.     def GetMessage(self, msgid, klass):
  433.         if msgid:
  434.             (msgfrom, msgto, msgsubject, body) = state.getMessage(str(msgid[3]), klass)
  435.             return Message(msgfrom, msgto, msgsubject, body)
  436.         else:
  437.             return Message()
  438.  
  439.     
  440.     def MoveToSpam(self, from_, messages):
  441.         '''Move messages to spam.
  442.  
  443.         messages should be an iterable of (msgfrom, emailsubject,
  444.         emaildate, msgid).
  445.         '''
  446.         idlist = [ str(item[3]) for item in messages ]
  447.         print 'move from', from_, 'to spam', idlist
  448.         for msg_info in messages:
  449.             if from_ == IS_HAM:
  450.                 self.removed_ham.append(msg_info[3])
  451.             elif from_ == IS_UNSURE:
  452.                 self.removed_unsure.append(msg_info[3])
  453.             
  454.             if msg_info[3] in self.removed_spam:
  455.                 self.removed_spam.remove(msg_info[3])
  456.             
  457.             self.added_spam.append(msg_info[3])
  458.             if msg_info[3] in self.added_ham:
  459.                 self.added_ham.remove(msg_info[3])
  460.             
  461.             if msg_info[3] in self.added_unsure:
  462.                 self.added_unsure.remove(msg_info[3])
  463.                 continue
  464.         
  465.         self.UpdateViews()
  466.         state.moveAndTrainMessages(idlist, from_, IS_SPAM)
  467.  
  468.     
  469.     def MoveToHam(self, from_, messages):
  470.         '''Move messages to ham.
  471.  
  472.         messages should be an iterable of (msgfrom, emailsubject,
  473.         emaildate, msgid).
  474.         '''
  475.         idlist = [ str(item[3]) for item in messages ]
  476.         print 'move from', from_, 'to ham', idlist
  477.         for msg_info in messages:
  478.             if from_ == IS_SPAM:
  479.                 self.removed_spam.append(msg_info[3])
  480.             elif from_ == IS_UNSURE:
  481.                 self.removed_unsure.append(msg_info[3])
  482.             
  483.             if msg_info[3] in self.removed_ham:
  484.                 self.removed_ham.remove(msg_info[3])
  485.             
  486.             self.added_ham.append(msg_info[3])
  487.             if msg_info[3] in self.added_spam:
  488.                 self.added_spam.remove(msg_info[3])
  489.             
  490.             if msg_info[3] in self.added_unsure:
  491.                 self.added_unsure.remove(msg_info[3])
  492.                 continue
  493.         
  494.         self.UpdateViews()
  495.         state.moveAndTrainMessages(idlist, from_, IS_HAM)
  496.  
  497.     
  498.     def MoveToUnsure(self, from_, messages):
  499.         '''Move messages to unsure.
  500.  
  501.         messages should be an iterable of (msgfrom, emailsubject,
  502.         emaildate, msgid).
  503.         '''
  504.         idlist = [ str(item[3]) for item in messages ]
  505.         print 'move from', from_, 'to unsure', idlist
  506.         for msg_info in messages:
  507.             if from_ == IS_HAM:
  508.                 self.removed_ham.append(msg_info[3])
  509.             elif from_ == IS_SPAM:
  510.                 self.removed_spam.append(msg_info[3])
  511.             
  512.             if msg_info[3] in self.removed_unsure:
  513.                 self.removed_unsure.remove(msg_info[3])
  514.             
  515.             self.added_unsure.append(msg_info[3])
  516.             if msg_info[3] in self.added_spam:
  517.                 self.added_spam.remove(msg_info[3])
  518.             
  519.             if msg_info[3] in self.added_ham:
  520.                 self.added_ham.remove(msg_info[3])
  521.                 continue
  522.         
  523.         self.UpdateViews()
  524.         state.moveAndTrainMessages(idlist, from_, IS_UNSURE)
  525.  
  526.     
  527.     def RemoveFromList(self, msgs, klass):
  528.         self.tray.SetBeginUpdating()
  529.         for view in self.views:
  530.             if hasattr(view, 'list') and hasattr(view.list, 'DeselectAll'):
  531.                 view.list.DeselectAll()
  532.                 continue
  533.         
  534.         to_remove = []
  535.         for msg_info in msgs:
  536.             if klass == IS_HAM:
  537.                 self.removed_ham.append(msg_info[3])
  538.             elif klass == IS_UNSURE:
  539.                 self.removed_unsure.append(msg_info[3])
  540.             else:
  541.                 self.removed_spam.append(msg_info[3])
  542.             to_remove.append(msg_info[3])
  543.         
  544.         self.UpdateViews()
  545.         thread = threading.Thread(target = self._do_remove, args = (to_remove, klass))
  546.         self.threads.append(thread)
  547.         thread.setDaemon(True)
  548.         thread.start()
  549.  
  550.     
  551.     def _do_remove(self, to_remove, klass):
  552.         for msg_info in to_remove:
  553.             state.removeMessageFromCorpus(msg_info, klass)
  554.         
  555.         self.tray.SetEndUpdating()
  556.  
  557.     
  558.     def GetWhiteList(self):
  559.         if self.active == VIEW_WHITE:
  560.             ret = { }
  561.             for i, address in enumerate(state.address_classifier.keys(is_spam = False)):
  562.                 ret[i + 1] = unicode(address)
  563.             
  564.             self.white_list = ret
  565.         
  566.         return self.white_list
  567.  
  568.     
  569.     def GetBlackList(self):
  570.         if self.active == VIEW_BLACK:
  571.             ret = { }
  572.             for i, address in enumerate(state.address_classifier.keys(is_spam = True)):
  573.                 ret[i + 1] = unicode(address)
  574.             
  575.             self.black_list = ret
  576.         
  577.         return self.black_list
  578.  
  579.     
  580.     def AddToWhitelist(self, email_list):
  581.         map(self.AddEmailToWhitelist, email_list)
  582.  
  583.     
  584.     def AddToBlacklist(self, email_list):
  585.         map(self.AddEmailToBlacklist, email_list)
  586.  
  587.     
  588.     def InBlacklist(self, email_list):
  589.         results = { }
  590.         for address in email_list:
  591.             results[address] = state.address_classifier.spamprob(address) == 1.0
  592.         
  593.         return results
  594.  
  595.     
  596.     def InWhitelist(self, email_list):
  597.         results = { }
  598.         for address in email_list:
  599.             results[address] = state.address_classifier.spamprob(address) == 0.0
  600.         
  601.         return results
  602.  
  603.     
  604.     def InAddressList(self, email_list):
  605.         results = []
  606.         for address in email_list:
  607.             prob = state.address_classifier.spamprob(address)
  608.             if prob == 1.0:
  609.                 isSpam = True
  610.             elif prob == 0.0:
  611.                 isSpam = False
  612.             else:
  613.                 isSpam = None
  614.             results.append(isSpam)
  615.         
  616.         return results
  617.  
  618.     
  619.     def DeleteFromWhitelist(self, email_list):
  620.         for email in email_list:
  621.             
  622.             try:
  623.                 state.address_classifier.unlearn(str(email), False)
  624.             continue
  625.             except UnicodeEncodeError:
  626.                 continue
  627.             
  628.  
  629.         
  630.         state.address_classifier.store()
  631.         self.UpdateViews()
  632.  
  633.     
  634.     def MoveToBlacklist(self, email_list):
  635.         for email in email_list:
  636.             
  637.             try:
  638.                 state.address_classifier.unlearn(str(email), True)
  639.             except UnicodeEncodeError:
  640.                 pass
  641.  
  642.             
  643.             try:
  644.                 state.address_classifier.learn(str(email), False)
  645.             continue
  646.             except UnicodeEncodeError:
  647.                 continue
  648.             
  649.  
  650.         
  651.         state.address_classifier.store()
  652.  
  653.     
  654.     def DeleteFromBlacklist(self, email_list):
  655.         for email in email_list:
  656.             
  657.             try:
  658.                 state.address_classifier.unlearn(str(email), True)
  659.             continue
  660.             except UnicodeEncodeError:
  661.                 continue
  662.             
  663.  
  664.         
  665.         state.address_classifier.store()
  666.         self.UpdateViews()
  667.  
  668.     
  669.     def MoveToWhitelist(self, email_list):
  670.         for email in email_list:
  671.             
  672.             try:
  673.                 state.address_classifier.unlearn(str(email), False)
  674.             except UnicodeEncodeError:
  675.                 pass
  676.  
  677.             
  678.             try:
  679.                 state.address_classifier.learn(str(email), True)
  680.             continue
  681.             except UnicodeEncodeError:
  682.                 continue
  683.             
  684.  
  685.         
  686.         state.address_classifier.store()
  687.  
  688.     
  689.     def AddEmailToBlacklist(self, email):
  690.         for encoding in ('ascii', 'latin-1', 'koi8-r'):
  691.             
  692.             try:
  693.                 email = email.encode(encoding)
  694.             except (UnicodeEncodeError, LookupError):
  695.                 continue
  696.  
  697.         
  698.         
  699.         try:
  700.             state.address_classifier.forget(email)
  701.         except UnicodeDecodeError:
  702.             print >>sys.stderr, 'Bad address database; should be removed.'
  703.  
  704.         
  705.         try:
  706.             state.address_classifier.learn(email, True)
  707.         except UnicodeDecodeError:
  708.             print >>sys.stderr, 'Bad address database; should be removed.'
  709.  
  710.         state.address_classifier.store()
  711.         self.UpdateViews()
  712.  
  713.     
  714.     def AddEmailToWhitelist(self, email):
  715.         for encoding in ('ascii', 'latin-1', 'koi8-r'):
  716.             
  717.             try:
  718.                 email = email.encode(encoding)
  719.             except (UnicodeEncodeError, LookupError):
  720.                 continue
  721.  
  722.         
  723.         
  724.         try:
  725.             state.address_classifier.forget(email)
  726.         except UnicodeDecodeError:
  727.             print >>sys.stderr, 'Bad address database; should be removed.'
  728.  
  729.         
  730.         try:
  731.             state.address_classifier.learn(email, False)
  732.         except UnicodeDecodeError:
  733.             print >>sys.stderr, 'Bad address database; should be removed.'
  734.  
  735.         state.address_classifier.store()
  736.         self.UpdateViews()
  737.  
  738.     
  739.     def ResetBlacklist(self):
  740.         '''Remove all entries from the blacklist.
  741.  
  742.         If the entry has whitelist counts, too (less than the blacklist
  743.         counts, obviously), then those are also removed.
  744.         '''
  745.         for address in state.address_classifier.keys(is_spam = True):
  746.             state.address_classifier.forget(address)
  747.         
  748.         state.address_classifier.store()
  749.  
  750.     
  751.     def ResetWhitelist(self):
  752.         '''Remove all entries from the whitelist.
  753.         
  754.         If the entry has blacklist counts, too (less than the whitelist
  755.         counts, obviously), then those are also removed.
  756.         '''
  757.         for address in state.address_classifier.keys(is_spam = False):
  758.             state.address_classifier.forget(address)
  759.         
  760.         state.address_classifier.store()
  761.  
  762.     
  763.     def ResetBayesianClassifier(self):
  764.         '''Completely reset the bayesian training database.
  765.  
  766.         All future messages will be classified (by the bayesian
  767.         system) as 0.5 until new training is carried out.'''
  768.         all_words = tuple(state.bayes._wordinfokeys())
  769.         for word in all_words:
  770.             state.bayes._wordinfodel(word)
  771.         
  772.         if not len(state.bayes._wordinfokeys()) == 0:
  773.             raise AssertionError, 'Reset did not work: %s keys left (%s)' % (len(state.bayes._wordinfokeys()), list(state.bayes._wordinfokeys()))
  774.         state.bayes.nham = 0
  775.         state.bayes.nspam = 0
  776.         state.bayes.store()
  777.  
  778.     
  779.     def ResetAll(self):
  780.         '''Reset white and blacklists and bayesian database, and
  781.         remove all cached mail.'''
  782.         self.ResetWhitelist()
  783.         self.ResetBlacklist()
  784.         self.ResetBayesianClassifier()
  785.         self._GetHam()
  786.         self._GetUnsure()
  787.         self._GetSpam()
  788.         ham = self.ham_list.itervalues()
  789.         unsure = self.unsure_list.itervalues()
  790.         spam = self.spam_list.itervalues()
  791.         for msg_info in ham:
  792.             state.removeMessageFromCorpus(msg_info[3], IS_HAM)
  793.         
  794.         for msg_info in unsure:
  795.             state.removeMessageFromCorpus(msg_info[3], IS_UNSURE)
  796.         
  797.         for msg_info in spam:
  798.             state.removeMessageFromCorpus(msg_info[3], IS_SPAM)
  799.         
  800.  
  801.     
  802.     def GetInterceptedAppData(self, path):
  803.         return (os.path.basename(path), '110,143', path)
  804.  
  805.     
  806.     def GetSettings(self):
  807.         return self.settings
  808.  
  809.     
  810.     def SetSettings(self, block, modSubj, tag, lang, mailapps, auto_report, user_address, date_header, auto_update, startup, vertical, periodic, enable_period, period, notify_sound, balloons):
  811.         self.settings.block_spam = block
  812.         self.settings.modify_subject_tag = tag
  813.         self.settings.modify_subject = modSubj
  814.         self.settings.modify_subject_tag = tag
  815.         for code, name in self.tray.languages.iteritems():
  816.             if name == lang:
  817.                 self.settings.lang = code
  818.                 break
  819.                 continue
  820.         
  821.         self.settings.mailapps = mailapps
  822.         self.settings.auto_bugreport = auto_report
  823.         self.settings.user_address = user_address
  824.         self.settings.date_header = date_header
  825.         self.settings.automatically_update = auto_update
  826.         self.settings.launch_on_startup = startup
  827.         self.settings.split_vertically = vertical
  828.         self.settings.enable_periodic = enable_period
  829.         if not self.settings.enable_periodic:
  830.             self.settings.periodic = []
  831.             self.settings.not_periodic = []
  832.         else:
  833.             self.settings.periodic = periodic[0]
  834.             self.settings.not_periodic = periodic[1]
  835.         self.settings.period = period
  836.         self.settings.notify_sound = notify_sound
  837.         self.settings.enable_balloon_notifications = balloons
  838.         self.UpdateViews()
  839.  
  840.     
  841.     def UpdateAutomatically(self):
  842.         return self.settings.automatically_update
  843.  
  844.     
  845.     def isUpdateAvailable(self):
  846.         vc = state.versioncontrol
  847.         return vc.checkForUpdate()
  848.  
  849.  
  850.